import Dictionary from "../structure/Dictionary";
import State from "./State";


export default class StateMachine {
    protected _stateDict: Dictionary = null;
    protected _currentState: State = null;
    protected _lastState: State = null;
    protected _globalState: State = null;
    protected _owner: Object = null;


    public constructor(owner: Object) {
        this._stateDict = new Dictionary();
        this._owner = owner;
    }


    public isExist(stateKey: string): boolean {
        return this._stateDict.containsKey(stateKey);
    }

    public getStateByKey(stateKey: string): State {
        return this._stateDict.get(stateKey) as State;
    }

    public setOwner(owner: Object): void {
        this._owner = owner;
    }

    /**
     * 注册状态
     * @param key 
     * @param state 
     */
    public registerState(key: string, state: State): void {
        if (this._owner != state.owner) {
            console.error('statemachine与state所有者不一致');
            return;
        }
        this._stateDict.add(key, state);
    }

    public setGlobalState(state: State, obj?: Object): void {
        this._globalState = state;
        this._globalState.onEnter(obj);
    }

    /**
     * 移除状态
     * @param key 
     */
    public removeState(key: string): void {
        this._stateDict.remove(key);
    }

    /**
     * 改变状态
     * @param key 
     * @param obj 
     */
    public changeState(key: string, obj?: Object): void {
        let newState: State = this._stateDict.get(key);
        if (!newState) {
            console.error('unregister state type:' + key);
            return;
        }

        if (this._currentState) this._currentState.onLeave(newState.getStateKey());

        this._lastState = this._currentState;
        this._currentState = newState;
        this._currentState.onEnter(obj);
    }

    public reEnterState(obj?: Object): void {
        if (this._currentState) this._currentState.onReEnter(obj);
    }

    /**
     * 更新
     */
    public update(): void {
        if (this._globalState) this._globalState.onUpdate();
        if (this._currentState) this._currentState.onUpdate();
    }

    /**
     * 当前状态类型
     */
    public getCurrentState(): string {
        if (this._currentState) return this._currentState.getStateKey();
        return State.InvalidState;
    }

    public clear(): void {
        if (this._globalState) this._globalState.onLeave(State.InvalidState);
        if (this._currentState) this._currentState.onLeave(State.InvalidState);

        this._stateDict.clear();
        this._stateDict = null;
        this._globalState = null;
        this._currentState = null;
        this._lastState = null;
        this._owner = null;
    }
}
